package com.stmt.stmtdesktop;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.stmt.stmtdesktop.DefaultServerRequest.TcpIpType;
import com.stmt.stmtdesktop.udp.DeviceEnum.DeviceInstruct;
import com.stmt.stmtdesktop.udp.NetUtil;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

/**
 * @author liangbo
 */
public class MainController {

  @FXML
  public Button ballResultBtn;
  @FXML
  public Button ballBackTimeoutBtn;
  @FXML
  public Button ballEarlyStopBtn;
  @FXML
  public TextField directiveField;
  public ListView<String> adView;
  public ImageView qrCodeView;
  @FXML
  private TextArea directiveIn;

  @FXML
  private TextArea directiveOut;

  @FXML
  private TextField hostTextField;

  @FXML
  private TextField portTextField;
  @FXML
  private TextField macnoTextField;

  private volatile boolean running = false;

  //订单号
  private String orderId;

  //当前帧
  private String frame = "000";

  private DeviceInstruct deviceInstruct = DeviceInstruct.C_HEALTH;

  private volatile boolean start = false;


  public void initialize() throws FileNotFoundException {

    doShowQrCode();

    adView.getItems()
        .addAll("广告1", "广告2", "广告3", "广告4", "广告5", "广告6", "广告7", "广告8", "广告9", "广告10","广告11","广告12");

    NetUtil.addSendListener(data -> directiveOut.appendText(data + "\n"));

    macnoTextField.textProperty().addListener((observable, oldValue, newValue) -> {
      try {
        doShowQrCode();
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      }
    });
  }

  private void doShowQrCode() throws FileNotFoundException {
    var qrCodeTmp = FileUtil.createTempFile(".png", true);

    QrCodeUtil.generate("https://ball.szxd730801.com/h5pro/?macno=" + macnoTextField.getText(), 300, 300, qrCodeTmp);

    qrCodeView.imageProperty().set(new Image(new FileInputStream(qrCodeTmp)));
  }

  @FXML
  protected void onBallStopClick() {
    if (this.start) {
      doStop();
      this.start = false;
    }
  }

  private void doStop() {
    this.start = false;
    NetUtil.closeUdp();
  }

  private void doReset() {
    this.running = false;
    this.frame = "000";
  }


  @FXML
  protected void startBallClick() {
    if (this.start) {
      this.running = true;
      NetUtil.sendMessage(1, String.format("$%s<%s><1002>", this.macnoTextField.getText(), this.frame));
    }
  }

  @FXML
  protected void onBallStartClick() {
    if (!this.start) {
      this.start = true;
      try {
        doStart();
      } catch (UnknownHostException e) {
        e.printStackTrace();
      }
    }
  }

  private void doStart() throws UnknownHostException {

    var hostStr = hostTextField.getText();
    var portStr = portTextField.getText();
    if (hostStr == null || hostStr.isEmpty()) {
      new Alert(AlertType.WARNING, "请填写host").show();
      return;
    }

    if (portStr == null || portStr.isEmpty()) {
      new Alert(AlertType.WARNING, "请填写port").show();
      return;
    }
    try {
      Integer.parseInt(portStr);
    } catch (NumberFormatException e) {
      new Alert(AlertType.WARNING, "port格式异常").show();
      return;
    }

    CompletableFuture.runAsync(() -> {
      try {
        NetUtil.startUdp(hostStr, Integer.valueOf(portTextField.getText()),
            (recvPacket -> {
              String res = new String(recvPacket.getData(), 0, recvPacket.getLength(), Charset.forName("GBK"));
              directiveIn.appendText(res + "\n");
              try {
                parseIns(res);
              } catch (Exception e) {
                e.printStackTrace();
              }
            }));
      } catch (Exception e) {
        e.printStackTrace();
      }
    });

    CompletableFuture.runAsync(() -> {
      while (this.start) {
        try {
          TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        var instruction = String.format("$%s<000><1001><000><0086><OK><000>", macnoTextField.getText());
        System.out.println("健康检查 " + instruction);
        NetUtil.sendMessage(1, instruction);
        try {
          TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    });
  }

  private void parseIns(String res) {
    var request = new DefaultServerRequest(res, TcpIpType.UDP);
    if (request.isResponse()) {
      System.out.println("应答指令");
      return;
    }
    this.frame = request.getFrame();
    this.deviceInstruct = request.getInstruction();

    if (request.getInstruction() == DeviceInstruct.S_START_SHOOT) {
      System.out.println("投篮订单");
      this.orderId = request.getParam(3);
    }

    if (request.getInstruction() == DeviceInstruct.S_ADV_UPDATE) {
      System.out.println("广告");
      var num = Integer.parseInt(request.getParam(3));
      String content = "-";
      try {
        content = request.getParam(7);
      } catch (Exception ignored) {

      }
      System.out.println(num);
      System.out.println(content);

      String finalContent = content;
      Platform.runLater(() -> adView.getItems().set(num - 1, "广告" + num + "-" + finalContent));
      resOkClick();

    }
  }

  @FXML
  public void ballResultClick() {
    if (this.start) {
      var hitNum = RandomUtil.randomInt(10, 40);
      var hitInRow = RandomUtil.randomInt(hitNum);

      NetUtil.sendMessage(1,
          String.format("$%s<%s><1003><%s><0100><040><%s>", this.macnoTextField.getText(), this.frame,
              this.orderId, hitNum));
    }
  }

  @FXML
  public void ballBackTimeoutClick() {
    if (this.start) {
      NetUtil.sendMessage(1,
          String.format("$%s<%s><1005><%s>", this.macnoTextField.getText(), this.frame, this.orderId));
    }
  }

  @FXML
  public void ballEarlyStopClick() {
    if (this.start) {
      NetUtil.sendMessage(1,
          String.format("$%s<%s><1006><%s> ", this.macnoTextField.getText(), this.frame, this.orderId));
    }
  }

  public void directiveSendClick() {
    if (this.start) {
      NetUtil.sendMessage(1, this.directiveField.getText());
    }
  }

  public void clearSendAreaClick() {
    this.directiveOut.clear();

  }

  public void clearReceiveAreaClick() {
    this.directiveIn.clear();
  }

  public void resOkClick() {
    if (this.start) {
      NetUtil.sendMessage(1,
          String.format("$%s<%s><%s><OK> ", this.macnoTextField.getText(), this.frame, this.deviceInstruct.getCode()));
    }
  }

  public void resErrorClick() {
    if (this.start) {
      NetUtil.sendMessage(1,
          String.format("$%s<%s><%s><ER> ", this.macnoTextField.getText(), this.frame, this.deviceInstruct.getCode()));
    }
  }
}